<?php

namespace RedMVC;

/**
 * Bootstrap class
 *
 * @category    RedMVC
 * @author      Jan Fischer, bitWorking <info@bitworking.de>
 */
class Bootstrap{
   
    private $config;

    /**
     * constructor
     */
    public function __construct(){
        if(version_compare(PHP_VERSION, '5.3.0', '<')){
            echo 'RedMVC only works with PHP Version 5.3.0 or higher.<br />';
            echo 'The installed version is '.PHP_VERSION;
            exit;
        }

        set_exception_handler(array($this, "handleException"));
        set_error_handler(array($this, "handleError"));
        spl_autoload_register(array($this, 'loader'));

        // config
        include(LIB_PATH.DS.'RedMVC'.DS.'Config.php');
        $this->config = new Config(APP_PATH.DS.'configs'.DS.'config.ini');

        Registry::set('RedMVC_Config', $this->config);
        // events
        Event\Loader::load();
        // db
        $this->dbConnect();
        
        Controller\Front::init();

        // translate
        $this->initTranslate();
    }

    /**
     * handles exceptions
     *
     * @param \Exception $e
     */
    public function handleException(\Exception $e){
        Registry::set('RedMVC_Exception', $e);
        Controller\Front::runControllerAction('error', 'index');
    }

    /**
     * handles errors
     *
     * @param int $errno
     * @param string $errstr
     * @param string $errfile
     * @param int $errline
     */
    public function handleError($errno, $errstr, $errfile, $errline){
        if($this->config->debugMode){
            //if($errno < 4000){
                Controller\Front::addError($errno.' - '.$errstr);
            //}
        }
    }

    /**
     * class autoloader
     * 
     * see https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
     *
     * @param string $className
     * @return void
     */
    public function loader($className){
        $classPath = DS.str_replace(NS, DS, $className).".php";
        foreach($this->config->searchPaths as $searchPath){
            $classPathFull = $searchPath.$classPath;            
            if(file_exists($classPathFull)){
                require_once $classPathFull;
                return;
            }
        }
    }

    /**
     * connects to db
     */
    protected function dbConnect(){
        $db = null;
        if($this->config->dbConnect){
            $dbAPI = $this->config->dbAPI;
            if(null === $dbAPI){
                $dbAPI = 'mysql';
            }
            if(('mysql' === $dbAPI) || ('mysqli' === $dbAPI)){
                if('mysql' === $dbAPI){
                    $db = new Db\MySql();
                }
                else if('mysqli' === $dbAPI){
                    $db = new Db\MySqli();
                }
                $db->connect(
                    $this->config->dbHost,
                    $this->config->dbName,
                    $this->config->dbUsername,
                    $this->config->dbPassword
                );
            }
            else if('pdo' === $dbAPI){
                $db = new Db\Pdo();
                $db->connect(
                    $this->config->dbDsn,
                    $this->config->dbUsername,
                    $this->config->dbPassword
                );
            }
        }
        Registry::set('RedMVC_Db', $db);
    }

    /**
     * initializes translate/locale
     */
    protected function initTranslate(){        
        $locale     = Locale::get();
        $localeFile = $this->config->localesPath.'/'.$locale.'.php';
        
        $translate  = new Translate();
        $translate->setData($localeFile);
        
        Registry::set('RedMVC_Translate', $translate);
        Registry::set('RedMVC_Locale', $locale);
    }

    /**
     * execute front controller run method
     */
    public function run(){        
        Controller\Front::run();
    }

}